//============================================================================
// Name        : RankBuilder.h
// Author      : lucmir@dcc.ufmg.br
// Description :
//============================================================================

#ifndef __RANK_BUILDER_H__
#define __RANK_BUILDER_H__

#include <stdio.h>
#include <string>
#include <sstream>
#include <math.h>
#include <algorithm>

#include "index/Index.h"
#include "index/DocumentIndex.h"
#include "index/Lexon.h"
#include "Rank.h"
#include "DocumentFeatures.h"

//#define PRINT_SCORE
#define ALL_RANK -1

// BM25 parameters default value
#define BM25_K	1.0
#define BM25_B	0.75

class RankBuilder {

	public:

		enum Model {
			BM25,
			VECTORIAL,
			COMBINED,
			PR,
			AT,
			PR_AT,
			ALL
		};

	private:

		enum Model model;
		DocumentIndex *docIdx;
		DocumentFeatures *docFeatures;
		Index *index;

		// BM25 parameters
		double k;
		double b;

	public:

		RankBuilder(DocumentIndex *docIdx, Index *index, DocumentFeatures *docFeatures);
		~RankBuilder();

		Rank *generateRank(std::string *query);
		void setModel(Model model);
		void printScores(Rank *rank, int rankLen);
		void printScores(Rank *rank, int rankLen, std::string fileName);

	private:

		// BM25 model
		void calcTermRankScoreBM25(Rank *rank, std::string *term);

		// Vectorial model
		void calcTermRankScoreVM(Rank *rank, std::string *term);
		void updateDocScoresVM(Rank *rank);

		// Combined model
		void calcTermRankScoreCM(Rank *rank, std::string *term);

		// Combined models with Page Rank and Anchor text
		void calcTermRankScoreCMWithPR(Rank *rank, std::string *term);
		void updateDocScoresPR(Rank *rank);

		void calcTermRankScoreCMWithAT(Rank *rank, std::string *term);

		void calcTermRankScoreCMWithPRAT(Rank *rank, std::string *term);

};

#endif
